﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;


namespace BloxGin.World
{
    class Terrain : IDisposable
    {
        public const float MaxHeight = 160;

        private VertexBuffer vertexBufer;
        private IndexBuffer IndexBuffer;
        private VertexPositionNormalTexture[] vertices;
        private int[] indices;

        public GraphicsDevice graphicsDevice { get; set; }
        public Randomness.HeightMap HeightMap { get; set; }

        public Terrain(GraphicsDevice device, Randomness.HeightMap heightmap)
        {
            this.graphicsDevice = device;
            this.HeightMap = heightmap;

        }

        public void LoadHeightMap(Randomness.HeightMap heightMap)
        {
            this.HeightMap = heightMap;
            this.HeightMap.Multiply(Terrain.MaxHeight);

            SetupVertices();
            SetupIndices();
            PostProcess(); ;
            SetupBuffers();
        }
        public void Dispose()
        {
        }
        private void SetupVertices()
        {
            int x, y, index, size = this.HeightMap.Size;
            this.vertices = new VertexPositionNormalTexture[size * size];

            for (x = 0; x < size; x++)
                for(y=0;y<size;y++)
                    for (int z = 0; z < size; z++)
                    {
                        index = x + y * size;

                        vertices[index].Position = new Vector3(x, this.HeightMap[x, y], -y);
                        vertices[index].Normal = Vector3.Zero;
                        vertices[index].TextureCoordinate = new Vector2(0.5f, 0);
                    }
            

        }
        private void SetupIndices()
        {
            int x, y, lowerLeft, lowerRight, topLeft, topRight;
            int counter = 0, size = this.HeightMap.Size;

            this.indices = new int[(size - 1) * (size - 1) * 6];
            for(y = 0; y< size-1; y++)
                for (x = 0; x < size - 1; x++)
                {
                    lowerLeft = x + y * size;
                    lowerRight = (x + 1) + y * size;
                    topLeft = x + (y + 1) * size;
                    topRight = (x + 1) + (y + 1) * size;

                    this.indices[counter++] = topLeft;
                    this.indices[counter++] = lowerRight;
                    this.indices[counter++] = lowerLeft;

                    this.indices[counter++] = topLeft;
                    this.indices[counter++] = topRight;
                    this.indices[counter++] = lowerRight;
                }
            
        }
        private void SetupBuffers()
        {
            this.Dispose();
            //this.vertexBufer = new VertexBuffer(graphicsDevice, typeof(VertexPositionNormalTexture), vertices.Length, BufferUsage.None);
          //  this.IndexBuffer = new IndexBuffer(graphicsDevice, IndexElementSize.ThirtyTwoBits, this.indices.Length, BufferUsage.None);

            this.vertexBufer.SetData<VertexPositionNormalTexture>(this.vertices);
            this.IndexBuffer.SetData<int>(this.indices);
        }

        private void PostProcess()
        {
            int i, index1, index2, index3;
            Vector3 side1, side2, normal;

            for (i = 0; i < this.indices.Length / 2; i++)
            {
                index1 = this.indices[i * 3];
                index2 = this.indices[i * 3 + 1];
                index3 = this.indices[i * 3 + 2];

                side1 = this.vertices[index1].Position - this.vertices[index3].Position;
                side2 = this.vertices[index1].Position - this.vertices[index2].Position;

                Vector3.Cross(ref side1, ref side2, out normal);

                this.vertices[index1].Normal += normal;
                this.vertices[index2].Normal += normal;
                this.vertices[index3].Normal += normal;
            }

            for (i = 0; i < this.vertices.Length; i++)
            {
                this.vertices[i].Normal.Normalize();
                this.vertices[i].TextureCoordinate.Y = +this.vertices[i].Normal.Y;
            }
        }

        private void Draw(BasicEffect effect)
        {
            if (effect == null)
                return;
            
        }
    }
}
